package com.airlines.crewassignment.controller.linkline;
/**
 * @author xxxx
 * @date 2018年6月14日 
 * @description
 */

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.airlines.base.config.response.ResponseResult;
import com.airlines.base.config.response.ResponseResultBuilder;
import com.airlines.base.entity.dict.Select2;
import com.airlines.common.ListSortUtil;
import com.airlines.crewassignment.dao.LinkLineMapper;
import com.airlines.crewassignment.domain.FlightInfo;
import com.airlines.crewassignment.domain.LinkLine;
import com.airlines.crewassignment.domain.Position;
import com.airlines.crewassignment.entity.linkline.TaskLoop;
import com.airlines.crewassignment.entity.linkline.fullcalendar.EventForFlight;
import com.airlines.crewassignment.entity.linkline.fullcalendar.Resource;
import com.airlines.crewassignment.service.dict.Select2Service;
import com.airlines.crewassignment.service.linkline.FullCalendarService;
import com.airlines.crewassignment.service.linkline.PositionService;
import com.airlines.crewassignment.service.linkline.TaskLoopFlightFactService;

@Controller
@RequestMapping("pilotLinkLine")
public class PilotLinkLineController {
	@Autowired
	private FullCalendarService fullCalendarService;
	@Autowired
	private Select2Service select2Service;
	@Autowired
	private PositionService positionService;
	
	@Autowired
	private LinkLineMapper linkLineMapper;
	
	@Autowired
	private TaskLoopFlightFactService taskLoopFlightFactService;
	
	@RequestMapping("toLinkLinePage")
	public String toLinkLinePage(String dutyCode,Model model){
		model.addAttribute("dutyCode", dutyCode);
		return "pilotAssign/linkLinePage";
	}
	
	@RequestMapping("listResource")
	@ResponseBody
	public List<Resource> listResource(@RequestParam(required=true) Date flightDate,@RequestParam(required=true)String dutyCode){
		List<Resource> list = fullCalendarService.listResource(dutyCode, flightDate);
		return  (list);
	}
	
	@RequestMapping("listEvent")
	@ResponseBody
	public List<EventForFlight> listEvent(@RequestParam(required=true) Date flightDate,@RequestParam(required=true)String dutyCode){
		List<EventForFlight> list = fullCalendarService.listEventForFlight(dutyCode, flightDate);
		return  (list);
	}
	
	/**
	 * 根据日期+连线号，查询未组连线航班
	 * @param flightDate
	 * @return
	 */
	@RequestMapping("listFlightNotHaveCrewLinkLine")
	@ResponseBody
	public List<FlightInfo> listFlightNotHaveCrewLinkLine(@RequestParam(required=true) Date flightDate,@RequestParam(required=true)String dutyCode){
		List<FlightInfo> list = fullCalendarService.listFlightNotHaveCrewLinkLine(dutyCode, flightDate);
		ListSortUtil.sort(list, true, "acLineLine","std");
		
		List<Select2> airportList = select2Service.getAirportCityCnName();
		Map<String,List<Select2>> map= new HashMap<>();
		map.put("departureAirport", airportList);
		map.put("arrivalAirport", airportList);			
		return  select2Service.convert(list, map) ;
	}
	
	/**
	 * 根据日期+连线号，查询已组航班
	 * @param flightDate
	 * @return
	 */
	@RequestMapping("listFlight")
	@ResponseBody
	public List<FlightInfo>  listFlight(@RequestParam(required=true) Date flightDate, @RequestParam(required=true) Integer crewLinkLineNo,@RequestParam(required=true)String dutyCode){
		List<FlightInfo> list = fullCalendarService.listFlight(dutyCode, flightDate,crewLinkLineNo);
		ListSortUtil.sort(list, true, "acLineLine","std");
		
		List<Select2> airportList = select2Service.getAirportCityCnName();
		Map<String,List<Select2>> map= new HashMap<>();
		map.put("departureAirport", airportList);
		map.put("arrivalAirport", airportList);			
		return  (select2Service.convert(list, map));
	}
	/**
	 * 根据日期+连线号，查询该连线对应的飞行员
	 * @param flightDate
	 * @param crewLinkLineNo
	 * @return
	 */
	@RequestMapping("listCrew")
	@ResponseBody
	public List<Position> listCrew(@RequestParam(required=true) Date flightDate, @RequestParam(defaultValue="0") Integer crewLinkLineNo,@RequestParam(required=true)String dutyCode){
		//查询该连线对应的飞行员号位
		Position p = new Position();
		p.setFlightDate(flightDate);
		p.setCrewLinkLineNo(crewLinkLineNo);
		p.setDutyCode(dutyCode);
		List<Position> list  = positionService.listPosition(p);
		ListSortUtil.sort(list, true, "serialNo");
		
		//将工号转换为姓名
		List<Position> convert = select2Service.convert(list, "workcode",select2Service.getCrewName());
		return  (convert);
	}
	
	/**
	 * 查询某个连线下所有航段的，已组任务环的航班信息
	 * @param flightDate
	 * @param crewLinkLineNo
	 * @return
	 */
	@RequestMapping("listFlightBySameTaskLoopFact")
	@ResponseBody
	public List<FlightInfo> listFlightBySameTaskLoopFact(@RequestParam(required=true) Date flightDate, @RequestParam(defaultValue="0") Integer crewLinkLineNo
			,@RequestParam(required=true)String dutyCode){
		List<FlightInfo> list = fullCalendarService.listFlightBySameTaskLoopFact(dutyCode, flightDate, crewLinkLineNo);
		if(CollectionUtils.isNotEmpty(list)){
			ListSortUtil.sort(list, true, "std");
			List<Select2> airportList = select2Service.getAirportCityCnName();
			Map<String,List<Select2>> map= new HashMap<>();
			map.put("departureAirport", airportList);
			map.put("arrivalAirport", airportList);		
			return  (select2Service.convert(list, map));	
		}
		return (list);
	}	
	
	/**
	 * 查询某一段时间内没有任务环的航班
	 * @param flightDateStart
	 * @param flightDateEnd
	 * @return
	 */
	@RequestMapping("listFlightNotHaveTaskLoopFact")
	@ResponseBody
	public List<FlightInfo> listFlightNotHaveTaskLoopFact(@RequestParam(required=true) Date flightDateStart
			,@RequestParam(required=true) Date flightDateEnd,@RequestParam(required=true)String dutyCode){
		List<FlightInfo> list = fullCalendarService.listFlightNotHaveTaskLoopFact(dutyCode,flightDateStart,flightDateEnd);
		ListSortUtil.sort(list, true, "flightDate","serial","std");

		List<Select2> airportList = select2Service.getAirportCityCnName();
		Map<String,List<Select2>> map= new HashMap<>();
		map.put("departureAirport", airportList);
		map.put("arrivalAirport", airportList);			
		return (select2Service.convert(list, map));
	}
	
	/**
	 * 根据日期+连线号，查询该连线所在任务环的概要指标信息
	 * @param flightDate
	 * @param crewLinkLineNo
	 * @return
	 */
	@RequestMapping("taskLoopInfo")
	@ResponseBody
	public Object  taskLoopInfo(@RequestParam(required=true) Date flightDate,@RequestParam(required=true) Integer crewLinkLineNo,@RequestParam(required=true)String dutyCode){
		TaskLoop taskLoop = fullCalendarService.getTaskLoopInfo(dutyCode,flightDate,crewLinkLineNo);
		return (ResponseResultBuilder.successResult(taskLoop,null));
	}
	
	
	//////////////////////////////////////////////////////////
	//以下是操作类别的控制器
	
	
	//获取一个连线号
	@RequestMapping("getNewCrewLinkLineNo")
	@ResponseBody
	public Object getNewCrewLinkLineNo(@RequestParam(required=true) Date flightDate,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		int newCrewLinkLineNo = fullCalendarService.getNewCrewLinkLineNo(dutyCode,flightDate);
		return (ResponseResultBuilder.successResult(newCrewLinkLineNo,null));
	}
	
	//将航班组成连线
	@RequestMapping("addFlightToLinkLine")
	@ResponseBody
	public Object  addFlightToLinkLine(@RequestParam(required=true)Integer flightId,
			@RequestParam(required=true) Date flightDate,
			@RequestParam(required=true) Integer crewLinkLineNo,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		
		//1.校验是否可以将某一个航班添加到连线中
		ResponseResult<String> ck = fullCalendarService.addFlightToLinkLineCk(flightId, dutyCode, flightDate, crewLinkLineNo);
		if(!ck.isSuccess()){
			return (ck);
		}
		
		//2.校验通过后，添加航班到连线中
		//判断是今天的连线，还是其他天的连线
		LinkLine l = fullCalendarService.getOrInitLinkLine(flightId, dutyCode, flightDate, crewLinkLineNo);
		fullCalendarService.addFlightToLinkLine(flightId, dutyCode, l.getFlightDate(), l.getCrewLinkLineNo(),l.getTaskLoopFact());
		
		return (ResponseResultBuilder.successResult());	
	}
	
	
	//将航班从连线拆除
	@RequestMapping("removeFlightFromLinkLine")
	@ResponseBody
	public Object  removeFlightFromLinkLine(@RequestParam(required=true)Integer flightId,
			@RequestParam(required=true) Date flightDate,
			@RequestParam(required=true) Integer crewLinkLineNo,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		//1.校验是可以将一个航班从连线中拆除
		ResponseResult<String> ck = fullCalendarService.removeFlightFromLinkLineCk(flightId, dutyCode, flightDate, crewLinkLineNo);
		if(!ck.isSuccess()){
			return (ck);
		}
		//2.校验通过后，航班从连线删除
		fullCalendarService.removeFlightFromLinkLine(flightId, dutyCode);
		
		return (ResponseResultBuilder.successResult());
	}
	
	//将航班从一个连线，移动到另外一个连线
	@RequestMapping("moveFlight")
	@ResponseBody
	public Object  moveFlight(@RequestParam(required=true)Integer flightId,
			@RequestParam(required=true) Date flightDate,
			@RequestParam(required=true) Integer crewLinkLineNoOld,
			@RequestParam(required=true) Integer crewLinkLineNoNew,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		
		//1.校验是可以将一个航班从连线中拆除
		ResponseResult<String> removeCk = fullCalendarService.removeFlightFromLinkLineCk(flightId, dutyCode, flightDate, crewLinkLineNoOld);
		if(!removeCk.isSuccess()){
			return (removeCk);
		}
		
		//2.校验是否可以将某一个航班添加到连线中
		ResponseResult<String> addCk = fullCalendarService.addFlightToLinkLineCk(flightId, dutyCode, flightDate, crewLinkLineNoNew);
		if(!removeCk.isSuccess()){
			return (addCk);
		}
		
		//3.校验通过后，先航班从连线删除，在移动到另外一个连线中
		fullCalendarService.moveFlight(flightId, dutyCode, flightDate, crewLinkLineNoOld,crewLinkLineNoNew);
		
		return (ResponseResultBuilder.successResult());
	}

	
	
	//删除一个连线
	@RequestMapping("deleteLinkLine")
	@ResponseBody
	public Object  deleteLinkLine(@RequestParam(required=true) Date flightDate,
			@RequestParam(required=true) Integer crewLinkLineNo,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		LinkLine linkLine = linkLineMapper.getLinkLine(flightDate, crewLinkLineNo, dutyCode);
		if(linkLine==null){
			return (ResponseResultBuilder.successResult());
		}
		
		ResponseResult<String> deleteCk = fullCalendarService.deleteLinkLineCk(dutyCode,flightDate,crewLinkLineNo);
		if(!deleteCk.isSuccess()){
			return (deleteCk);
		}
		fullCalendarService.deleteLinkLine(dutyCode,flightDate,crewLinkLineNo);
		return (ResponseResultBuilder.successResult());
	}
	

	//将某个连线上的航班，创建一个新的任务环（从原来的任务环拿掉）
	@RequestMapping("createNewTaskLoopFact")
	@ResponseBody
	public Object  createNewTaskLoopFact(@RequestParam(required=true) Date flightDate,
			@RequestParam(required=true) Integer crewLinkLineNo,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		fullCalendarService.createNewTaskLoopFact(dutyCode, flightDate, crewLinkLineNo);
		return (ResponseResultBuilder.successResult());
	}
	
	/**
	 * 将某个连线所对应的任务环航班，加入到另外一个任务环中
	 * @param flightDate
	 * @param crewLinkLineNo
	 * @return
	 */
	@RequestMapping("moveTaskLoop")
	@ResponseBody
	public Object  moveTaskLoop(@RequestParam(required=true) Date flightDate,
			@RequestParam(required=true) Integer crewLinkLineNo,@RequestParam(required=true) Integer crewLinkLineNoMoveTo,
			@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		fullCalendarService.moveTaskLoop(dutyCode, flightDate, crewLinkLineNo,crewLinkLineNoMoveTo);
		return (ResponseResultBuilder.successResult());
	}
	
	//删除一个连线
	@RequestMapping("deleteTaskLoop")
	@ResponseBody
	public Object  deleteTaskLoop(@RequestParam(required=true) Date flightDate,
			@RequestParam(required=true) Integer crewLinkLineNo,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		ResponseResult<String> deleteCk = fullCalendarService.deleteTaskLoopCk(dutyCode,flightDate,crewLinkLineNo);
		if(!deleteCk.isSuccess()){
			return (deleteCk);
		}
		fullCalendarService.deleteTaskLoop(dutyCode,flightDate,crewLinkLineNo);
		return (ResponseResultBuilder.successResult());
	}
	
	//新增过站休息期
	@RequestMapping("arrivalAirportRestTime")
	@ResponseBody
	public Object  arrivalAirportRestTime(@RequestParam(required=true) int flightId,int restTime,@RequestParam(required=true)String dutyCode){
		taskLoopFlightFactService.updateRestTime(dutyCode, flightId, restTime);
		return (ResponseResultBuilder.successResult());
	}
	
	/**
	 * 将某一天的连线确认
	 * 确认逻辑：
	 * 1.当天没有未组连线的航班
	 * 2.每个航班的任务环是完整的（基地出、基地回）
	 * 3.任务环中的航班首位相连，时间不能冲突
	 * @param flightDate
	 * @return
	 */
	@RequestMapping("confirm")
	@ResponseBody
	public Object  confirm(@RequestParam(required=true) Date flightDate,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		
		ResponseResult<String> confirmCk = fullCalendarService.confirmCk(dutyCode, flightDate);
		if(!confirmCk.isSuccess()){
			return (confirmCk);
		}
		fullCalendarService.confirm(dutyCode, flightDate);
		return (ResponseResultBuilder.successResult());
	}
	
	
	/**
	 * 将某个任务标记为差航线
	 * @param flightDate
	 * @param crewLinkLineNo
	 * @param badRoute true：坏航线，false：正常航线，null：正常航线
	 * @return
	 */
	@RequestMapping("badRoute")
	@ResponseBody
	public Object  badRoute(@RequestParam(required=true) Date flightDate,@RequestParam(required=true) Integer crewLinkLineNo,
			@RequestParam(required=true)Boolean badRoute,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		if(badRoute == null){
			badRoute  = false;
		}
		fullCalendarService.badRoute(dutyCode, flightDate,crewLinkLineNo,badRoute);
		return (ResponseResultBuilder.successResult());
	}
	
	/**
	 * 将某个任务环标记最少的男性数量
	 * @param flightDate
	 * @param crewLinkLineNo
	 * @param minMale
	 * @param dutyCode
	 * @return
	 */
	@RequestMapping("minMale")
	@ResponseBody
	public Object  minMale(@RequestParam(required=true) Date flightDate,@RequestParam(required=true) Integer crewLinkLineNo,
			@RequestParam(required=true)Integer minMale,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		if(minMale == null){
			minMale  = 0;
		}
		fullCalendarService.minMale(dutyCode, flightDate,crewLinkLineNo,minMale);
		return (ResponseResultBuilder.successResult());
	}
	
	/**
	 * 手动将某个任务环设置为国际航线差6时区
	 * @param flightDate
	 * @param crewLinkLineNo
	 * @param internationalTimeZoneMore6
	 * @param dutyCode
	 * @return
	 */
	@RequestMapping("internationalTimeZoneMore6")
	@ResponseBody
	public Object  internationalTimeZoneMore6(@RequestParam(required=true) Date flightDate,@RequestParam(required=true) Integer crewLinkLineNo,
			@RequestParam(required=true)Boolean internationalTimeZoneMore6,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		if(internationalTimeZoneMore6 == null){
			internationalTimeZoneMore6  = false;
		}
		fullCalendarService.internationalTimeZoneMore6(dutyCode, flightDate,crewLinkLineNo,internationalTimeZoneMore6);
		return (ResponseResultBuilder.successResult());
	}
	
	
	
	@RequestMapping("crewType")
	@ResponseBody
	public Object  updateCrewType(@RequestParam(required=true) Date flightDate,@RequestParam(required=true) Integer crewLinkLineNo,
			@RequestParam(required=true)Integer crewType,@RequestParam(required=true)String dutyCode){
		if(!fullCalendarService.flightDateCk(flightDate, flightDate)){
			return (ResponseResultBuilder.errorResult(null, "该日期不能执行操作", "400")); 
		}
		fullCalendarService.updateCrewTypeId(dutyCode, flightDate,crewLinkLineNo,crewType);
		return (ResponseResultBuilder.successResult());
	}
	
		
}
